#pragma once

#define INITGUID

#include <windows.h>
#include "EngineObject.h"
#include "ISerializable.h"
#include "ISerializerReadContext.h"

class IEngineComponentCollection;

// {34AEF631-D1A0-4fd8-BF8E-95AFB9F9C377}
DEFINE_GUID(NULL_SYSTEM, 
0x34aef631, 0xd1a0, 0x4fd8, 0xbf, 0x8e, 0x95, 0xaf, 0xb9, 0xf9, 0xc3, 0x77);

class IEngineComponent;

typedef IEngineComponent* (*IEngineComponentDeserializer)(EnginePointer<ISerializerReadContext>&);

typedef struct IEngineComponentStringCmp: binary_function<char const *, char const*, bool>
{
	bool operator()(char const* g1, char const* g2) const
	{
		return strcmp(g1, g2) < 0;
	}
} IEngineComponentStringCmp;

class IEngineComponent : public ISerializable
{
public:
	IEngineComponent() { componentId = nextComponentId++; }
	virtual GUID getSystemIdentifier() = 0;
	virtual GUID getComponentIdentifier() = 0;
	virtual void Serialize(EnginePointer<ISerializerWriteContext>& context, char* name) = 0;
	virtual void Initialize(EnginePointer<IEngineComponentCollection> components);
	
	static IEngineComponent* Deserialize(EnginePointer<ISerializerReadContext>& context);

	long long int getId() { return componentId; }
protected:
	long long int componentId;
private:
	static long long int nextComponentId;
};

class IEngineComponentRegistry
{
public:
	IEngineComponentRegistry(char* type, IEngineComponentDeserializer deserializer);
	static map<char*, IEngineComponentDeserializer, IEngineComponentStringCmp>* getDeserializerMap();
};